package com.whfp.coky.ui.task.vm.fluor

import android.media.SoundPool
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer
import com.blankj.utilcode.util.EncodeUtils
import com.blankj.utilcode.util.FlashlightUtils
import com.tencent.mmkv.MMKV
import com.whfp.afs330h_sdk.bean.BLE_TestingResultBean
import com.whfp.afs330h_sdk.bean.BLE_TestingResultBean.ItemBean
import com.whfp.afs330h_sdk.zx
import com.whfp.coky.R
import com.whfp.coky.api.RequestBodyBuild
import com.whfp.coky.ble.BleController
import com.whfp.coky.databinding.ActivityFluorMainBinding
import com.whfp.coky.databinding.FragFluorDetectionBinding
import com.whfp.coky.db.DbFlowTools
import com.whfp.coky.db.dao.JsonBQDao
import com.whfp.coky.db.dao.TestingRecordingDao
import com.whfp.coky.other.Constants
import com.whfp.coky.ui.base.BaseActivity
import com.whfp.coky.ui.base.vm.NavigationActVM
import com.whfp.coky.ui.task.frag.FluorDetecFrag
import com.whfp.coky.ui.task.model.FluorSettingBean
import com.whfp.coky.ui.task.model.SearchBQBean
import com.whfp.coky.ui.task.model.TestVoBean
import com.whfp.coky.ui.task.model.ThresholdInfoBean
import com.whfp.coky.utils.CaculateBQUtil
import com.whfp.coky.utils.GsonUtils
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import java.nio.charset.Charset


/**
 *
 *
 * created by coky on 2022/3/1
 */

class FluorMainVM : NavigationActVM<ActivityFluorMainBinding>() {
    enum class BQ_HANDLE {
        //获取标曲处理方式（写入，保存）
        WRITE, SAVE
    }


    //    base
    val mmkv = MMKV.defaultMMKV()//本体缓存
    var BC: BleController? = null//蓝牙控制器
//    var checkDevLD = MutableLiveData<CheckDeviceBean>()//设备校验结果
    var cloudBqLD = MutableLiveData<SearchBQBean>()//云端标曲

    //    配置信息实体类
    var settingBean: FluorSettingBean = mmkv.decodeParcelable(
        Constants.MMKV_FLUOR_SETTINGS, FluorSettingBean::class.java,
        FluorSettingBean()
    )!!//检测设置实体类

    //    设备蓝牙相关
    var handleBQ: BQ_HANDLE = BQ_HANDLE.WRITE//云端标曲默认写入操作
    var doAlarmLD = MutableLiveData(false)//默认不进行声光报警

    //检测结果数据源
    private var testVoBeans = mutableListOf<TestVoBean>()

    //    声音播放
    private val soundPool: SoundPool by lazy { initSoundPool() }
    private var FLASH_TIMES: Int = 12//闪光次数
    private val FLASH_DURING: Long = 500//闪光间隔
    private var currFlashTime: Int = FLASH_TIMES//当前剩余闪光次数

    fun initSoundPool(): SoundPool {
        return SoundPool.Builder()
            .setMaxStreams(1)
            .setAudioAttributes(null)
            .build()
    }

    //--------------------回调和观察----------------------------------------
    override fun observe(activity: BaseActivity<*, *>, owner: LifecycleOwner) {
        super.observe(activity, owner)

        cloudBqLD.observe(owner, Observer {
//            云端标曲下载完成后
            when (handleBQ) {
                BQ_HANDLE.WRITE -> {
//                    写入设备
                    cloudBqLD.value?.bq_content?.let {
                        BC?.writeProjectToDevice(
                            it,
                            settingBean.detecType,
                            settingBean.isCoverOldProj
                        )
                    }
                }
                BQ_HANDLE.SAVE -> {
//                    保存标曲
                    DbFlowTools.insertBqJson(JsonBQDao().apply {
                        bqName = it.biaoQuName
                        bqContent = it.bq_content
                        DbFlowTools.insertBqJson(this)
//                        jsonBQDao1.setBqName(bqbh);
//                        jsonBQDao1.setBqContent(GsonUtils.toJson(bqBean));
                    })
                    updateTestingResult(
                        CaculateBQUtil.calculationResult(
                            currTestResultBean?.curve,it)
                    )
                }
            }
        })

        doAlarmLD.observe(owner, Observer {
            if (it) {
//                声光报警
                currFlashTime = FLASH_TIMES
                soundPool.load(activity, R.raw.bj, 1);
                soundPool.play(1, 1f, 1f, 0, 0, 1f)
                activity.postDelayed(object : Runnable {
                    override fun run() {
                        FlashlightUtils.setFlashlightStatus(!FlashlightUtils.isFlashlightOn())
                        currFlashTime--
                        if (currFlashTime <= 0) {
                            doAlarmLD.value = false
                        } else {
                            activity.postDelayed(this, FLASH_DURING)
                        }
                    }
                }, 300)
            } else {
//          声光报警取消
                FlashlightUtils.setFlashlightStatus(false)
                FlashlightUtils.destroy()
            }
        })
    }

    fun test(activity: BaseActivity<*, *>){
        runBlocking {
            soundPool.load(activity, R.raw.bj, 1);
            soundPool.play(1, 1f, 1f, 0, 0, 1f)
            try {
                launch{
                    repeat(FLASH_TIMES){
                        FlashlightUtils.setFlashlightStatus(!FlashlightUtils.isFlashlightOn())
                        delay(FLASH_DURING)
                    }
                }
            }finally {
                FlashlightUtils.setFlashlightStatus(false)
                FlashlightUtils.destroy()
            }
        }

    }


    //    数据保存
    fun storeDev() {
        //保存校验设备
        mmkv.encode(Constants.CACHE_DEVICE_INFO_PB2_PBEHY, checkedDevLD.value)
    }

    fun storePrint(mac: String) {
        //保存校验打印机
        mmkv.encode(Constants.CACHE_PRINT, "ZXLDYJ-01$mac")
    }

    //更新项目
    fun updateProj(result: String?) {

    }


    var originValue: String = ""//原始值
    var currTestResultBean: BLE_TestingResultBean? = null//当前测试结果实体类
    fun handleTestingResult(bean: BLE_TestingResultBean) {
        currTestResultBean = bean
        if (settingBean.lowUpCaculate) {
//        新的流程加入了上位机计算
            queryBqJson(getBqNum())
        } else {
//            旧的流程获取原始值直接上传
            updateTestingResult()
        }
    }

    private fun buildTestingDao(): TestingRecordingDao {
        return TestingRecordingDao().apply {
            this.testingProject = String(
                EncodeUtils.base64Decode(currTestResultBean?.title),
                Charset.forName("GB2312")
            )

            (fragList.value!![0].vBinding as FragFluorDetectionBinding).let {
                this.barCode = it.sbSampleCode.getLeftText().toString().trim()
                this.name = it.etName.text.toString()
                this.sex = it.tvSex.text.toString()
                this.id_card = it.etIdCard.text.toString()
                this.yblx = it.spSampleType.text.toString()
                this.remark = it.etRemark.text.toString()
            }
            this.testUserId = "username"
//                  外部获取
            this.testLocation = ""
            this.testLocationX = ""
            this.testLocationY = ""

            this.serialNumber = "????"
            this.testingTime = "????"
            this.testingResultJson = com.blankj.utilcode.util.GsonUtils.toJson(testVoBeans)
            this.filesPath = "???"
            this.pb2Mac = zx.instance().currentDevice.mac
        }
    }


    //    获取标曲编号
    private fun getBqNum(): String {
        return when (settingBean.curveType) {//一卡一码
//                一卡一码时获取样本码
            2 -> (fragList.value!![0].vBinding as FragFluorDetectionBinding).sbSampleCode.getLeftText()
                .toString().trim()
//               其他情况获取试剂码
            else -> (fragList.value!![0].vBinding as FragFluorDetectionBinding).spReagent.text.toString()
                .trim()
        }
    }

    //    查询标曲
    private fun queryBqJson(bqNum: String) {
        val jsonBQDao = DbFlowTools.inquiryToBqName(bqNum)
        if (jsonBQDao == null) {
            doGetCloudBq(bqNum, BQ_HANDLE.SAVE)
        }
    }

    //    处理测试结果
    private fun updateTestingResult(caculateResultList: ArrayList<TestVoBean>? = null) {
        if (caculateResultList == null) {
//          旧的流程:获取原始值 originValue
            currTestResultBean?.curve?.let {
                val sb = StringBuffer()
                for (value in it) {
                    sb.append(value.toString()).append(",")
                }
                originValue = sb.substring(0, sb.length - 1).toString()
            }
            if (currTestResultBean?.item?.size!! > 0){
                testVoBeans.clear()
            }



        } else {
//            新的流程:上位机计算
            testVoBeans.clear()
            var itemBeans = mutableListOf<ItemBean>()
            //匹配阈值设置
            for (testVoBean in caculateResultList) {
                //检测出来的浓度值修正（小于0的显示为0）
                val origin = if (testVoBean.potency?.toDouble()!! < 0) 0.0 else testVoBean.potency!!.toDouble()

                DbFlowTools.inquiryToName(testVoBean.drugsName)?.let {
                    val thresholdSettings: MutableList<ThresholdInfoBean> =
                        GsonUtils.jsonToArrayList(
                            it.thresholdInfo,
                            ThresholdInfoBean::class.java
                        )
                    //浓度值单位
                    testVoBean.unit = it.densityUnit
                    //显示的判定结果
                    for (b in thresholdSettings) {
                        if (origin >= b.lowerLimit && origin < b.upperLimit) {
                            testVoBean.result = b.displayText
                        }
                    }
                }
                testVoBeans.add(testVoBean)

                if (testVoBean.result.equals("阳性") && !doAlarmLD.value!!) {
                    doAlarmLD.value = true
                }

                itemBeans.add(ItemBean().apply {
                    this.name = testVoBean.drugsName
                    this.value = testVoBean.result
                    this.unit = testVoBean.unit
                    this.cValue = testVoBean.cValue!!.toDouble()
                    this.tValue = testVoBean.tValue!!.toDouble()
                    this.origin = testVoBean.potency!!.toDouble()
                })
            }
            currTestResultBean?.item = itemBeans
            //保存本次检测记录
            DbFlowTools.insertTestingData(buildTestingDao())?.let {
                doUploadAll(it)
            }
            //刷新底部检测结果
            (fragList.value?.get(0) as FluorDetecFrag).let {
                it.loadBottomDatas(testVoBeans)
                it.clearInfos()
                it.changeView(settingBean.isShowResult)
            }

        }
    }


//--------------------------------http请求-----------------------------------------------

    //       上传检测结果
    fun doUploadAll(dao: TestingRecordingDao) {
        if (dao.filesPath.isNotEmpty()){
//        先上传人员图片
        }else{

        }
    }


    //       下载云标曲
    fun doGetCloudBq(
        bqName: String,
        handler: BQ_HANDLE = BQ_HANDLE.WRITE
    ) {
        handleBQ = handler
        val map = HashMap<String, String>()
        map["bq_bh"] = bqName
        launch({ httpUtil.doCloudBQ(body = RequestBodyBuild.buildBodyByMap(map)) }, cloudBqLD, true)
    }


// -------------------蓝牙开启和资源释放-------------------------------------

    /**
     * 打印机连接act入口
     */
    fun connPrint() {
        BC?.isBleOpend(BleController.DEV_TYPE.PRINT)
    }

    /**
     * 设备连接act入口
     */
    fun connDev() {
        BC?.isBleOpend(BleController.DEV_TYPE.DEV)
    }

    /**
     * act 销毁
     * 保存setting,清除BC
     */
    fun release() {
        mmkv.encode(Constants.MMKV_FLUOR_SETTINGS, settingBean)
        BC?.printBt = null
        BC = null
    }


    override fun getNavigationBottom() = vBinding.rvFluorNavigation

    override fun getNavigationBody() = vBinding.vpFluor

}